package com.yixun.qfbao.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.PascalNameFilter;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yixun.qfbao.common.request.CommonRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

import java.io.StringWriter;
import java.util.Iterator;
import java.util.Map;

public class RestTemplateUtil {

    private static final Logger logger = LoggerFactory.getLogger(RestTemplateUtil.class);

    private static final String ACCEPT = "Accept";

    private RestTemplateUtil(){
    }

    private static class SingletonRestTemplate{
        private final static RestTemplate instance = new RestTemplate();
    }

    private static RestTemplate getInstance(){
        return SingletonRestTemplate.instance;
    }

    public static String get(String url) {
        return RestTemplateUtil.getInstance().getForObject(url, String.class);
    }

    public static String post(String url, Map<String,Object> map){
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
        HttpEntity request = new HttpEntity(map, headers);
        ResponseEntity<String> response = RestTemplateUtil.getInstance().postForEntity(url, request, String.class);
        return response.getBody();
    }

	public static String buildGetUrl(String uri, Map map){
		StringBuilder strBuilder = new StringBuilder();
		strBuilder.append(uri).append("?");
		for(Iterator it = map.entrySet().iterator(); it.hasNext();) {
			Map.Entry entry = (Map.Entry) it.next();
			strBuilder.append(entry.getKey());
			strBuilder.append("=");
			strBuilder.append(entry.getValue());
			strBuilder.append("&");
		}
		return strBuilder.toString().substring(0, strBuilder.length() - 1);
	}

    public static <T> T post(String url, Map<String,Object> map, Class<T> cla){
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
        HttpEntity request = new HttpEntity(map, headers);
        ResponseEntity<T> response = RestTemplateUtil.getInstance().postForEntity(url, request, cla);
        logger.info(response.toString());
        logger.info(response.getStatusCode()+"==="+response.getStatusCodeValue()+"==="+response.getBody());
        return response.getBody();
    }

	public static <T> T get(String url,Class<T> cla) {
		return RestTemplateUtil.getInstance().getForObject(url, cla);
	}

    public static <T> T sendHttp(RestTemplate restTemplate, String url, CommonRequest request, Class<T> target, HttpHeaders headers) {
        MediaType type = MediaType.parseMediaType(MediaType.APPLICATION_JSON_UTF8_VALUE);
        headers.setContentType(type);
        headers.add(ACCEPT, MediaType.APPLICATION_JSON_VALUE);
        HttpEntity<Object> formEntity = new HttpEntity<>(request, headers);
        return restTemplate.postForObject(url, formEntity, target);
    }

    public static <T> T sendHttpByMapParam(RestTemplate restTemplate, String url, Map<String, Object> requestMap, Class<T> target, HttpHeaders headers) {
        MediaType type = MediaType.parseMediaType(MediaType.APPLICATION_JSON_UTF8_VALUE);
        headers.setContentType(type);
        headers.add(ACCEPT, MediaType.APPLICATION_JSON_VALUE);
        HttpEntity formEntity = new HttpEntity(requestMap, headers);
        return restTemplate.postForObject(url, formEntity, target);
    }

    public static <T> T sendHttpByJson(RestTemplate restTemplate, String url, Object postObj, Class<T> target, HttpHeaders headers) {
        MediaType type = MediaType.parseMediaType(MediaType.APPLICATION_JSON_UTF8_VALUE);
        headers.setContentType(type);
        headers.add(ACCEPT, MediaType.APPLICATION_JSON_VALUE);
        HttpEntity<String> formEntity = new HttpEntity<>(writeBeanToJson(postObj), headers);
        return restTemplate.postForObject(url, formEntity, target);
    }

    public static <T> T sendHttpByJsonUpper(RestTemplate restTemplate, String url, Object postObj, Class<T> target, HttpHeaders headers) {
        MediaType type = MediaType.parseMediaType(MediaType.APPLICATION_JSON_UTF8_VALUE);
        headers.setContentType(type);
        headers.add(ACCEPT, MediaType.APPLICATION_JSON_VALUE);
        HttpEntity<String> formEntity = new HttpEntity<>(writeBeanToJsonByUpper(postObj), headers);
        return restTemplate.postForObject(url, formEntity, target);
    }

    /**
     * 将 Bean 对象转换为 json 字符串
     */
    private static <T> String writeBeanToJson(T classObj) {
        if (classObj != null) {
            try {
                StringWriter json = new StringWriter();
                ObjectMapper mapper = new ObjectMapper();
                mapper.writeValue(json, classObj);
                return json.toString();
            } catch (Exception e) {
                logger.error("format bean to json error: {}", e);
            }
        }
        return null;
    }

    /**
     * 将 Bean 对象转换为 json 字符串
     */
    private static <T> String writeBeanToJsonByUpper(T classObj) {
        if (classObj != null) {
            return JSON.toJSONString(classObj, new PascalNameFilter());
        }
        return null;
    }

}
